package com.angcyo.selenium.auto.parse

import com.angcyo.javafx.base.OSInfo
import com.angcyo.javafx.base.ex.onBack
import com.angcyo.library.ex.*
import com.angcyo.log.L
import com.angcyo.selenium.DriverWebElement
import com.angcyo.selenium.auto.*
import com.angcyo.selenium.auto.action.Action
import com.angcyo.selenium.auto.action.arg
import com.angcyo.selenium.auto.action.toKeyValue
import com.angcyo.selenium.bean.*
import com.angcyo.selenium.isValid
import org.openqa.selenium.*
import org.openqa.selenium.support.locators.RelativeLocator.withTagName
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.math.max
import kotlin.math.min
import kotlin.random.Random
import kotlin.random.Random.Default.nextBoolean

/**
 * Email:angcyo@126.com
 * @author angcyo
 * @date 2020/12/31
 */
class AutoParse(val control: BaseControl? = null) {

    /**数值解析*/
    val valueParse = ValueParse(control)

    companion object {

        /**配置浏览器窗口大小*/
        fun configWindow(driver: WebDriver?, configBean: ConfigBean?) {
            if (driver != null && configBean != null) {
                driver.manage().window().apply {
                    if (configBean.rect == null) {
                        when {
                            configBean.maximize -> maximize()
                            configBean.minimize -> minimize()
                            configBean.fullscreen -> fullscreen()
                        }
                    } else {
                        configWindow(
                            driver,
                            ValueParse().parseRect(
                                configBean.rect,
                                Rectangle(0, 0, size.height, size.width)
                            )
                        )
                    }
                }
            }
        }

        /**配置浏览器窗口大小*/
        fun configWindow(driver: WebDriver?, rect: Rectangle?) {
            if (driver != null && rect != null) {
                driver.manage().window().apply {
                    //设置窗口位置
                    val x = if (rect.x.isValid()) rect.x else position.x
                    val y = if (rect.y.isValid()) rect.y else position.y
                    position = Point(x, y)

                    //设置窗口大小
                    val w = if (rect.width.isValid()) rect.width else size.width
                    val h = if (rect.height.isValid()) rect.height else size.height
                    size = Dimension(w, h)
                }
            }
        }

        /**根据系统, 随机获取一个时长*/
        fun randomTime(): Long {
            return if (OSInfo.isMac) {
                Random.nextLong(800, 1800)
            } else {
                Random.nextLong(1200, 2200)
            }
        }
    }

    /**获取bounds*/
    fun getBounds(): Rectangle {
        val size = control?.driver?.manage()?.window()?.size
        return Rectangle(0, 0, size?.width ?: 0, size?.height ?: 0)
    }

    /**
     * 解析时间格式
     * 格式[5000,500,5] 解释:5000+500*[1-5),
     * 返回解析后的时间, 毫秒*/
    fun parseTime(arg: String?, def: Long = 0): Long {
        return if (arg.isNullOrEmpty()) {
            def
        } else {
            val split = arg.split(",")

            //时长
            val start = split.getOrNull(0)?.toLongOrNull() ?: def

            //基数
            val base = split.getOrNull(1)?.toLongOrNull() ?: randomTime()

            //倍数
            val factor = split.getOrNull(2)?.toLongOrNull() ?: 1 //nextLong(2, 5)

            start + base * Random.nextLong(1, max(2L, factor + 1))
        }
    }

    /**解析文本
     * $0 从[com.angcyo.selenium.bean.TaskBean.wordList] 取第一个
     * $-2 从[com.angcyo.selenium.bean.TaskBean.wordList] 取倒数第二个
     * $0~$-2 取范围内的字符
     * $[xxx] 从[com.angcyo.selenium.bean.TaskBean.textMap]获取[xxx]键值对应的值
     * */
    fun parseText(control: BaseControl, arg: String?): List<String> {
        if (arg.isNullOrEmpty()) {
            return emptyList()
        }
        val result = mutableListOf<String>()

        var isHandle = false

        //$0~$-2
        val indexStringList = arg.patternList("\\$[-]?\\d+")
        if (indexStringList.isNotEmpty()) {
            val wordList = control._currentTaskBean?.wordList ?: emptyList()
            //$xxx 的情况
            if (arg.havePartition()) {
                //$0~$1
                if (indexStringList.size >= 2) {
                    isHandle = true
                    val startIndex = indexStringList[0].getLongNum()?.revise(wordList.size) ?: 0
                    val endIndex = indexStringList[1].getLongNum()?.revise(wordList.size) ?: 0

                    wordList.forEachIndexed { index, word ->
                        if (index in startIndex..endIndex) {
                            result.add(word)
                        }
                    }
                } else {
                    isHandle = true
                    indexStringList.forEach { indexString ->
                        indexString.getLongNum()?.let { index ->
                            wordList.getOrNull(index.toInt())?.let { word ->
                                result.add(word)
                            }
                        }
                    }
                }
            } else {
                //$0
                isHandle = true
                indexStringList.forEach { indexString ->
                    indexString.getLongNum()?.let { index ->
                        wordList.getOrNull(index.toInt())?.let { word ->
                            result.add(word)
                        }
                    }
                }
            }
        }

        //$[xxx], 在map中获取文本
        val mapKeyList = arg.patternList("(?<=\\$\\[).+(?=\\])")
        if (mapKeyList.isNotEmpty()) {
            isHandle = true
            mapKeyList.forEach { key ->
                control._currentTaskBean?.textMap?.get(key)?.let { value ->
                    result.add(value)
                }
            }
        }

        if (!isHandle) {
            //都未处理
            result.add(arg)
        }

        if (result.isEmpty()) {
            control.logAction?.invoke("无法解析文本参数[$arg].")
        }

        return result
    }

    /**选择器解析*/
    fun _selectorParse(context: SearchContext, selectorBean: List<SelectorBean>, result: MutableList<WebElement>) {
        selectorBean.forEach {
            _selectorParse(context, it, result)
        }
    }

    /**切换到目标框架*/
    fun _switchToFrame(context: SearchContext, frameBean: FrameBean): Boolean {
        var result = false
        val countDownLatch = CountDownLatch(1)
        onBack(false) {
            try {
                if (context is WebDriver) {
                    frameBean.apply {
                        if (_frame != null) {
                            control?.logAction?.invoke("已在iframe框架:${_frame}")
                            result = true
                        } else {
                            val locator = context.switchTo()
                            if (select != null) {
                                val frameElementList = mutableListOf<WebElement>()
                                _selectorParse(context, select!!, frameElementList)
                                frameElementList.firstOrNull()?.let {
                                    control?.logAction?.invoke("选择iframe框架:$select")
                                    _frame = locator.frame(it)
                                }
                            }
                            if (_frame == null && !frameId.isNullOrEmpty()) {
                                control?.logAction?.invoke("选择iframe框架id:$frameId")
                                _frame = locator.frame(frameId)
                            }
                            if (_frame == null && !frameName.isNullOrEmpty()) {
                                control?.logAction?.invoke("选择iframe框架name:$frameName")
                                _frame = locator.frame(frameName)
                            }
                            if (_frame == null && frameIndex >= 0) {
                                control?.logAction?.invoke("选择iframe框架index:$frameIndex")
                                _frame = locator.frame(frameIndex)
                            }
                            result = _frame != null
                            //退出框架
                            if (defaultContent == true) {
                                control?.logAction?.invoke("退出iframe框架.")
                                _frame = null
                                result = locator.defaultContent() != null
                            }
                        }
                    }
                }
            } catch (e: Exception) {
                L.e("异常:$e")
                control?.logAction?.invoke("选择iframe框架异常:$e")
                e.printStackTrace()
            }
            countDownLatch.countDown()
        }
        try {
            countDownLatch.await(2, TimeUnit.SECONDS)
        } catch (e: Exception) {
        }
        if (result) {
            control?.logAction?.invoke("选择iframe框架:${frameBean._frame}")
        }
        return result
    }

    /**选择器解析*/
    fun _selectorParse(context: SearchContext, selectorBean: SelectorBean, result: MutableList<WebElement>) {
        val list = mutableListOf<WebElement>()

        //frame
        if (context is WebDriver) {
            var isSwitchFrame = false
            var ignoreFrame = false
            if (selectorBean.frame == null && selectorBean.frameList.isNullOrEmpty()) {
                //不需要切换iframe
                isSwitchFrame = true
            } else {
                //选择iframe
                selectorBean.frame?.apply {
                    isSwitchFrame = _switchToFrame(context, this)
                    ignoreFrame = this.ignore || ignoreFrame
                }

                if (!isSwitchFrame) {
                    if (selectorBean.frameList != null) {
                        for (frameBean in selectorBean.frameList!!) {
                            ignoreFrame = frameBean.ignore || ignoreFrame
                            if (_switchToFrame(context, frameBean)) {
                                isSwitchFrame = true
                                break
                            }
                        }
                    }
                }
            }
            if (ignoreFrame) {
                //忽略切换结果
            } else if (!isSwitchFrame) {
                //框架切换失败
                control?.logAction?.invoke("iframe切换失败")
                return
            }
        }

        //-----------------------------选择元素--------------------------

        val noCss = selectorBean.cssList == null
        val noText = selectorBean.textList == null
        val noTag = selectorBean.tagList == null
        val noAttr = selectorBean.attrList == null
        val noRect = selectorBean.rectList == null

        //css
        if (!noCss) {
            val findList = selectorBean.cssList!!.eachMatchItem { index, item ->
                val control = control
                val css = if (control == null) item else parseText(control, item).firstOrNull()
                if (css != null) {
                    context.findByCss(css).run {
                        val cssSize = this.size
                        _matchElementAttr(this, selectorBean.attrList?.getOrNull(index)).run {
                            _matchElementRect(this, selectorBean.rectList?.getOrNull(index))
                        }.apply {
                            val filterSize = this.size
                            if (this.isNotEmpty()) {
                                control?.logAction?.invoke(toLog("css[$css]匹配到${cssSize}后$filterSize↓"))
                            }
                        }
                    }
                } else {
                    emptyList()
                }
            }
            list.addAll(findList)
        }

        //text
        if (!noText) {
            val findList = selectorBean.textList!!.eachMatchItem { index, item ->
                //根据text查找元素
                val control = control
                val text = if (control == null) item else parseText(control, item).firstOrNull()
                if (text != null) {
                    val tags = selectorBean.tags ?: TAGS
                    context.findByText(text, tags) { noTextList ->
                        val maxCount = if (tags.contains("div")) 0 else 5
                        val max = min(maxCount, noTextList.size)
                        val more = if (noTextList.size > max) "\n..." else ""
                        control?.logAction?.invoke("匹配的文本集合[${noTextList.size}]:${noTextList.subList(0, max)}${more}")
                    }.run {
                        val textSize = this.size
                        _matchElementAttr(this, selectorBean.attrList?.getOrNull(index)).run {
                            _matchElementRect(this, selectorBean.rectList?.getOrNull(index))
                        }.apply {
                            val filterSize = this.size
                            if (this.isNotEmpty()) {
                                control?.logAction?.invoke(toLog("text[$text]匹配到${textSize}后$filterSize↓"))
                            }
                        }
                    }
                } else {
                    emptyList()
                }
            }
            list.addAll(findList)
        }

        //tag
        if (!noTag) {
            val findList = selectorBean.tagList?.eachMatchItem { index, tagStr ->
                context.findByTag(tagStr).run {
                    val tagSize = this.size
                    _matchElementAttr(this, selectorBean.attrList?.getOrNull(index)).run {
                        _matchElementRect(this, selectorBean.rectList?.getOrNull(index))
                    }.apply {
                        val filterSize = this.size
                        if (this.isNotEmpty()) {
                            control?.logAction?.invoke(toLog("tag[$tagStr]匹配到${tagSize}后$filterSize↓"))
                        }
                    }
                }
            } ?: emptyList()
            list.addAll(findList)
        }

        //attr
        if (noCss && noText && noTag && !noAttr) {
            //根据attr, 重新选择元素
            val findList = selectorBean.attrList?.eachMatchItem { index, attrStr ->
                context.findByTag(selectorBean.tags ?: TAGS).run {
                    val attrSize = this.size
                    _matchElementAttr(this, attrStr).run {
                        _matchElementRect(this, selectorBean.rectList?.getOrNull(index))
                    }.apply {
                        val filterSize = this.size
                        if (this.isNotEmpty()) {
                            control?.logAction?.invoke(toLog("attr[$attrStr]匹配到${attrSize}后$filterSize↓"))
                        }
                    }
                }
            } ?: emptyList()
            list.addAll(findList)
        }

        //rect
        if (noCss && noText && noAttr && noTag && !noRect) {
            //根据rect, 重新选择元素
            val findList = selectorBean.rectList?.eachMatchItem { index, rectStr ->
                context.findByTag(selectorBean.tags ?: TAGS).run {
                    val rectSize = this.size
                    _matchElementRect(this, rectStr).run {
                        _matchElementAttr(this, selectorBean.attrList?.getOrNull(index))
                    }.apply {
                        val filterSize = this.size
                        if (this.isNotEmpty()) {
                            control?.logAction?.invoke(toLog("rect[$rectStr]匹配到${rectSize}后$filterSize↓"))
                        }
                    }
                }
            } ?: emptyList()
            list.addAll(findList)
        }

        //空的选择器
        if (noCss && noText && noAttr && noTag && noRect) {
            if (context is WebElement) {
                //来自内部的二次查询
                list.add(context)
            }
        }

        //------------------------后处理-------------------------

        //需要过滤
        if (selectorBean.filter != null) {
            val filterList = _filterElement(list, selectorBean.filter)
            list.clear()
            list.addAll(filterList)
        }

        //递归处理
        var afterList: MutableList<WebElement>? = null
        if (selectorBean.after != null) {
            afterList = mutableListOf()
            list.forEach { element ->
                _selectorParse(element, selectorBean.after!!, afterList)
            }
        }

        //-----------------------返回结果--------------------------

        //返回选择的目标元素
        result.addAll(afterList ?: list)
    }

    /**匹配符合矩形要求的元素
     * 返回满足矩形要求的元素集合*/
    fun _matchElementRect(list: List<WebElement>?, rectStr: String?): List<WebElement> {
        if (rectStr == null || list.isNullOrEmpty()) {
            return list ?: emptyList()
        }

        val result = mutableListOf<WebElement>()
        val rectValue = valueParse.parseRectValue(rectStr, getBounds())

        //log
        control?.logAction?.invoke("解析矩形:$rectStr ->$rectValue")

        list.forEach { element ->
            if (valueParse.matchRect(element.rect, rectStr, rectValue)) {
                //矩形匹配
                result.add(element)
            }
        }
        return result
    }

    /**匹配符合属性要求的元素*/
    fun _matchElementAttr(list: List<WebElement>?, attrStr: String?): List<WebElement> {
        if (attrStr == null || list.isNullOrEmpty()) {
            return list ?: emptyList()
        }

        val attrPairList = attrStr.toKeyValue()

        if (attrPairList.isEmpty()) {
            return list
        }

        val result = mutableListOf<WebElement>()

        //单个匹配
        fun match(element: WebElement, pair: Pair<String, String?>): Boolean {
            val key = pair.first
            val value = pair.second

            //当属性是`disabled="disabled"`时, 返回的是"true"
            val attribute = element.getAttribute(key)
            return when {
                value == null -> attribute == value
                value.isEmpty() -> attribute.isNullOrEmpty()
                else -> attribute.have(value)
            }
        }

        //全部匹配
        fun matchAll(element: WebElement, list: List<Pair<String, String?>>): Boolean {
            var allResult = true
            for (pair in list) {
                allResult = match(element, pair)
                if (!allResult) {
                    break
                }
            }
            return allResult
        }

        //匹配
        list.forEach { element ->
            if (matchAll(element, attrPairList)) {
                result.add(element)
            }
        }
        return result
    }

    /**
     * 过滤元素
     * 返回过滤之后的元素集合
     * */
    fun _filterElement(list: List<WebElement>?, filterBean: FilterBean?): List<WebElement> {

        //查找需要移除的元素, 也就是被过滤的元素
        val removeList = _filterElementByRemove(list, filterBean)

        //过滤后的集合
        val result = mutableListOf<WebElement>()
        list?.filterTo(result) { !removeList.contains(it) }

        //相对定位 https://www.selenium.dev/documentation/zh-cn/getting_started_with_webdriver/locating_elements/
        //above 元素上
        //below 元素下
        //toLeftOf 元素左
        //toRightOf 元素右
        //near 附近
        filterBean?.let {
            if (!it.relativeBy.isNullOrBlank()) {
                val relativeList = mutableListOf<WebElement>()
                result.forEach { element ->
                    val splitList = it.relativeBy.args()
                    val tagName = splitList.getOrNull(0)
                    val by = splitList.getOrNull(1)
                    val byLocation = by?.getLongNum()//偏移距离
                    val indexString = splitList.getOrNull(2)
                    if (!tagName.isNullOrEmpty() && !by.isNullOrEmpty()) {
                        //标签不为空时, 才有效
                        element.findElements(withTagName(tagName).run {
                            when {
                                by.startsWith("above") -> above(element)
                                by.startsWith("below") -> below(element)
                                by.startsWith("toLeftOf") -> toLeftOf(element)
                                by.startsWith("toRightOf") -> toRightOf(element)
                                else -> near(element)
                            }
                        })?.eachRangeItem(indexString) { item, isIn ->
                            if (isIn) {
                                if (byLocation != null) {

                                    val targetElementRect = element.rect
                                    val dl = byLocation.toInt()

                                    //取偏移距离对应的元素
                                    var x: Int = targetElementRect.centerX()
                                    var y: Int = targetElementRect.centerY()

                                    when {
                                        by.startsWith("above") -> {
                                            y = targetElementRect.top()
                                            y -= dl
                                        }
                                        by.startsWith("below") -> {
                                            y = targetElementRect.bottom()
                                            y += dl
                                        }
                                        by.startsWith("toLeftOf") -> {
                                            x = targetElementRect.left()
                                            x -= dl
                                        }
                                        by.startsWith("toRightOf") -> {
                                            x = targetElementRect.right()
                                            x += dl
                                        }
                                        else -> {
                                            y += dl
                                            x += dl
                                        }
                                    }

                                    if (item.rect.contains(x, y)) {
                                        relativeList.add(item)
                                    }
                                } else {
                                    relativeList.add(item)
                                }
                            }
                        }
                    }
                }
                //将匹配到的元素返回回去
                result.clear()
                result.addAll(relativeList)
            }
        }
        return result
    }

    /**
     * 过滤元素
     * 返回不满足条件的元素集合
     * */
    fun _filterElementByRemove(list: List<WebElement>?, filterBean: FilterBean?): List<WebElement> {
        if (list == null || filterBean == null) {
            return emptyList()
        }

        //过滤之后的元素集合
        var afterList: List<WebElement>? = list

        //不满足条件的元素
        val removeList = mutableListOf<WebElement>()

        //过滤筛选步骤1: index
        val indexString = filterBean.index
        if (indexString != null) {
            list.eachRangeItem(indexString) { item, isIn ->
                if (!isIn) {
                    removeList.add(item)
                }
            }
        }

        //过滤筛选步骤2: containList
        //剩下的元素集合
        afterList = if (removeList.isEmpty()) afterList else afterList?.filter { !removeList.contains(it) }
        if (!filterBean.containList.isNullOrEmpty()) {
            afterList?.forEach { element ->
                val result = mutableListOf<WebElement>()
                _selectorParse(element, filterBean.containList ?: emptyList(), result)
                if (result.isEmpty()) {
                    //不包含目标, 不符合过滤条件
                    removeList.add(element)
                }
            }
        }

        //过滤筛选步骤3: notContainList
        afterList = if (removeList.isEmpty()) afterList else afterList?.filter { !removeList.contains(it) }
        if (!filterBean.notContainList.isNullOrEmpty()) {
            afterList?.forEach { element ->
                val result = mutableListOf<WebElement>()
                _selectorParse(element, filterBean.notContainList ?: emptyList(), result)
                if (result.isNotEmpty()) {
                    //包含目标, 不符合过滤条件
                    removeList.add(element)
                }
            }
        }

        //过滤筛选步骤4: tagList
        afterList = if (removeList.isEmpty()) afterList else afterList?.filter { !removeList.contains(it) }
        if (!filterBean.tagList.isNullOrEmpty()) {
            afterList?.forEach { element ->
                if (filterBean.tagList?.contains(element.tagName) == true) {
                    //包含指定的tag
                } else {
                    //不包含元素的标签
                    removeList.add(element)
                }
            }
        }

        //过滤筛选步骤5: rectList
        afterList = if (removeList.isEmpty()) afterList else afterList?.filter { !removeList.contains(it) }
        if (!filterBean.rectList.isNullOrEmpty()) {

            var matchElementList = afterList //满足条件的元素集合
            for (rectStr in filterBean.rectList!!) {
                matchElementList = _matchElementRect(matchElementList, rectStr)
                if (matchElementList.isEmpty()) {
                    break
                }
            }

            afterList?.forEach { element ->
                if (matchElementList?.contains(element) == true) {
                    //满足条件
                } else {
                    //不满足条件
                    removeList.add(element)
                }
            }
        }

        return removeList
    }

    /**通过指定的选择器, 返回目标元素*/
    fun parseSelector(control: BaseControl, selectorList: List<SelectorBean>?): List<WebElement> {
        val result = mutableListOf<WebElement>()

        when {
            control.driver == null -> L.e("驱动为空!")
            selectorList == null -> L.e("无选择器!")
            else -> _selectorParse(control.driver!!, selectorList, result)
        }

        //选中元素后的提示
        control.showElementTip(result)

        return result
    }

    /**处理目标, 返回处理过的元素*/
    fun handle(
        control: BaseControl,
        actionBean: ActionBean,
        handleList: List<HandleBean>?,
        originList: List<WebElement>? = null /*之前解析返回的元素列表*/
    ): HandleResult {
        val result = HandleResult()
        if (handleList == null) {
            result.success = false
            result.elementList = null
        } else if (handleList.isEmpty()) {
            result.success = true
            result.elementList = originList
        } else {
            //处理

            //处理成功了的元素列表
            val handleElementList = mutableListOf<WebElement>()
            for (handleBean in handleList) {

                //条件判断
                if (handleBean.conditionList != null &&
                    !parseCondition(control, handleBean.conditionList)
                ) {
                    control.logAction?.invoke("未满足条件, 跳过处理:$handleBean")
                    continue
                }

                //执行单个[HandleBean]
                val handleResult = handle(control, actionBean, handleBean, originList)
                result.success = handleResult.success || result.success

                if (handleResult.success) {
                    handleElementList.addAll(handleResult.elementList ?: emptyList())
                }
                if (handleBean.jump) {
                    //跳过后续处理
                    break
                }
                if (handleBean.jumpOnSuccess && handleResult.success) {
                    //成功之后跳过后续处理
                    break
                }
            }

            //总体处理成功
            if (result.success) {
                result.elementList = handleElementList
            }
        }
        return result
    }

    /**执行[HandleBean]*/
    fun handle(
        control: BaseControl,
        actionBean: ActionBean,
        handleBean: HandleBean,
        originList: List<WebElement>? = null
    ): HandleResult {
        val result = HandleResult()

        //内部执行
        fun handleInner() {
            //需要操作的元素
            val elementList: List<WebElement> = if (handleBean.selectList == null) {
                //如果没有重新执行选择列表, 则使用之前选择的元素
                originList ?: listOf(DriverWebElement(getBounds()))
            } else {
                //重新选择元素
                parseSelector(control, handleBean.selectList)
            }

            //满足过滤条件之后, 需要处理的元素集合
            val filterElementList = _filterElement(elementList, handleBean.filter)

            //处理成功了的元素列表
            val handleElementList = mutableListOf<WebElement>()

            //do
            val needHandleElementList: List<WebElement>
            val needHandleActionList: List<String>?
            if (filterElementList.isNullOrEmpty() && !handleBean.noActionList.isNullOrEmpty()) {
                needHandleElementList = listOf(DriverWebElement(getBounds()))
                needHandleActionList = handleBean.noActionList
            } else {
                needHandleElementList = filterElementList
                needHandleActionList = handleBean.actionList
            }

            //BaseAction分配处理
            if (needHandleActionList.isNullOrEmpty()) {
                handleElementList.clear()
                result.success = needHandleActionList != null
            } else {
                needHandleElementList.forEach { element ->
                    //枚举actionList
                    needHandleActionList.forEach { action ->
                        //处理action
                        control.handleAction(actionBean, element, action).apply {
                            result.success = success || result.success
                            if (success) {
                                //把处理成功的元素收集起来
                                if (!handleElementList.containsAll(this.elementList ?: emptyList())) {
                                    handleElementList.addAll(this.elementList!!)
                                }
                            }
                        }
                    }
                }
            }

            //如果处理成功,
            if (result.success) {
                result.elementList = handleElementList
            }

            //后置处理
            if (handleBean.ignore) {
                control.logAction?.invoke("忽略[handle]结果:${handleBean}")
                result.success = false
            }
        }

        //eachText处理
        val eachText = handleBean.eachText
        if (eachText.isNullOrEmpty()) {
            handleInner()
        } else {
            val mapTextParam = eachText.args(" ").firstOrNull()
            if (mapTextParam.isNullOrEmpty()) {
                handleInner()
            } else {
                val mapText = control._autoParse.parseText(control, mapTextParam).firstOrNull() ?: ""

                val indexParam = eachText.arg("index")
                val keyParam = eachText.arg("key") ?: "eachText"

                //文本集合
                val mapTextList = mapText.split(" ")

                //最终需要处理的文本集合
                val textList = mapTextList.eachRangeItem(indexParam)

                //返回
                if (textList.isEmpty()) {
                    result.success = true
                    if (handleBean.ignore) {
                        control.logAction?.invoke("忽略[handle]结果2:${handleBean}")
                        result.success = false
                    }
                    return result
                }

                //循环赋值, 并执行
                for (text in textList) {
                    control._currentTaskBean?.putMap(keyParam, text)
                    handleInner()
                }
            }
        }

        //退出框架
        handleBean.selectList?.forEach {
            if (it.frame?._frame != null) {
                control.logAction?.invoke("退出[handle]iframe:${it.frame}")
                it.frame?._frame = null
                control.driver?.switchTo()?.defaultContent()
            }
        }

        return result
    }

    /**解析条件, 判断是否满足条件*/
    fun parseCondition(control: BaseControl, conditionList: List<ConditionBean>?): Boolean {
        return if (conditionList.isNullOrEmpty()) {
            true
        } else {
            var result = false
            for (condition in conditionList) {
                if (_conditionParse(control, condition)) {
                    //有一个满足条件即可
                    result = true
                    break
                }
            }
            result
        }
    }

    //判断单个条件, 是否满足
    fun _conditionParse(control: BaseControl, condition: ConditionBean?): Boolean {
        var result = true
        condition?.apply {
            //random
            if (random) {
                result = nextBoolean()
            }

            //textMapList
            if (!textMapList.isNullOrEmpty()) {
                for (key in textMapList!!) {
                    val value = control._currentTaskBean?.textMap?.get(key)
                    if (value == null) {
                        //指定key对应的value没有值, 则条件不满足
                        result = false
                        break
                    }
                }
            }

            //actionResultList
            if (result && !actionResultList.isNullOrEmpty()) {
                for (actionId in actionResultList!!) {
                    if (control.actionResultMap[actionId] != true) {
                        //指定id的action执行失败, 则条件不满足
                        result = false
                        break
                    }
                }
            }

            //检查次数是否满足表达式
            fun checkCount(expression: String, countGetAction: (actionId: Long) -> Long): Boolean {
                val actionExp = expression.subStart(Action.ARG_SPLIT)
                val actionId = actionExp?.toLongOrNull()
                val exp = expression.subEnd(Action.ARG_SPLIT)
                if (!exp.isNullOrEmpty()) {
                    val actionBean = if (actionExp == ".") {
                        control.actionSchedule._currentActionBean
                    } else {
                        control.findAction(actionId)
                    }

                    if (actionBean != null) {
                        val expValue = valueParse.toValueExp(exp)
                        val count = countGetAction(actionBean.actionId)
                        if (!valueParse.matchValue(count.toFloat(), expValue)) {
                            //运行次数不满足条件
                            return false

                        }
                    }
                }
                return true
            }

            //actionRunList
            if (result && !actionRunList.isNullOrEmpty()) {
                for (expression in actionRunList!!) {
                    if (!checkCount(expression) {
                            control.actionSchedule.getRunCount(it)
                        }) {
                        //运行次数不满足条件
                        result = false
                        break
                    }
                }
            }

            //actionJumpList
            if (result && !actionJumpList.isNullOrEmpty()) {
                for (expression in actionJumpList!!) {
                    if (!checkCount(expression) {
                            control.actionSchedule.getJumpCount(it)
                        }) {
                        //跳转次数不满足条件
                        result = false
                        break
                    }
                }
            }

            //actionEnableList
            if (result && !actionEnableList.isNullOrEmpty()) {
                for (actionId in actionEnableList!!) {
                    val actionBean = control.findAction(actionId)
                    if (actionBean != null) {
                        if (!actionBean.enable) {
                            //未激活, 则不满足条件
                            result = false
                            break
                        }
                    }
                }
            }
        }
        return result
    }
}